#include<iostream>
#include<typeinfo>
#include<string>

// class Any
// {
// private:
//     class base
//     {
//     public:
//         base(){}
//         virtual ~base(){}
//         virtual const std::type_info& GetType() = 0;
//         virtual base* clone() = 0;
//     };
//     template<class T>
//     class derive:public base 
//     {
//     public:
//         T _val;
//     public:
//         derive(const T& val):_val(val) {}

//         const std::type_info& GetType(){  return typeid(T);  }

//         derive* clone(){    return new derive<T>(_val);    }
//     };
// private:
//     base* _ptr;
// private:
//     Any& swap(Any& ay){  std::swap(ay._ptr,_ptr);  return *this; }
// public:
//     template<class T>
//     Any(const T& data = T()) :_ptr(new derive<T>(data)) {} //实例化一个空对象
//     Any(const Any& ay):_ptr(ay._ptr?ay._ptr->clone():nullptr){} //用一个Any对象，实例化另一个Any对象
//     ~Any(){  delete _ptr;  }

//     template<class T>
//     Any& operator=(const T& data){   Any(data).swap(*this); /*优化点————移动拷贝*/  return *this;  }
//     Any& operator=(Any ay){   swap(ay);  return *this;   } //Any a=2; Any b = "abc";  a=b;  


//     template<class T>
//     T* GetAddress(){  if(typeid(T)==_ptr->GetType()) return &(((derive<T>*)_ptr)->_val); else return nullptr; }

// };

// class test{
//     public:
//         test(){   std::cout<<"构造"<<std::endl;    }
//         test(const test& tt){   std::cout<<"拷贝"<<std::endl;   }
//         ~test(){    std::cout<<"析构"<<std::endl;   }
// };

// int main()
// {
//     Any a=10;
//     int* pi=a.GetAddress<int>();
//     std::cout<<*pi<<std::endl;

//     a=std::string("abc");
//     std::string *ps=a.GetAddress<std::string>();
//     std::cout<<*ps<<std::endl;

//     a=test();

//     a=(const char*)"hello world";//"hello world"默认会被当成一个数组

//     return 0;
// }

//通用类Any，可实现: Any a;  a=10;  a="abc";
//要用到模版，但又不能显示实例化，多态，通过父类指针访问子类成员，绕过“显示实例化”
class Any
{
private:
    class parent
    {
    public:
        virtual ~parent(){};//析构函数必须是虚函数，否则无法构造析构函数的多态，造成内存泄漏
        virtual parent* clone()=0; //构成多态的条件:1.父类虚函数(public权限)  2.子类重写
        virtual const std::type_info& GetType()=0;
    };
    template<class T>
    class child:public parent 
    {
    public:
        T _data;
    public:
        child(const T& data=T()):_data(data){}
        child* clone(){  return new child<T>(_data);  }  //函数重写：三同(函数名，参数，返回类型)，邪变除外
        const std::type_info& GetType(){  return typeid(T);  }
    };
private:
    parent* _ptr;//父类指针，指向子类对象，才能访问子类成员
public:
    Any():_ptr(nullptr){}
    Any(const Any& ay):_ptr(ay._ptr==nullptr?ay._ptr->clone():nullptr){}
    template<class T>
    Any(const T& data):_ptr(new child<T>(data)){}

    ~Any(){  delete _ptr;  }

    void swap(Any& ay){
        std::swap(_ptr,ay._ptr);
    }

    template<class T>
    Any& operator=(const T& data){
        Any(data).swap(*this); //匿名对象能被引用吗？？？————不能
        return *this;
    }
    Any& operator=(const Any& ay){
        Any(ay).swap(*this);
        return *this;
    }

    template<class T>
    T* GetAddress(){  if(typeid(T)==_ptr->GetType())return &(((child<T>*)_ptr)->_data); else return nullptr;  }
};

int main()
{
    Any a;
    a=10;
    a=std::string("nihao");

    std::string* str=a.GetAddress<std::string>();
    std::cout<<*str<<std::endl;

    return 0;
}